﻿namespace Hotel.Module.Resources.Models
{
    using System;
    using System.Collections.ObjectModel;
    using Entities = Hotel.Module.Resources.DataRepository;
    using System.Collections.Generic;
   
    
    public class Room : Model.Infrastructure.IDistributedStorageEntity
    {

        /// <summary>
        /// Creates a new Instance of Room according to recived Entity room instance
        /// </summary>
        /// <param name="entity">Entity Room object from which new Room instance will be created</param>
        public static Room FromEnityModel(Entities.Room entity)
        {
            Room result = new Room();
            if (entity == null)
            {
                return null;
            }
            else
            {
                result.Capacity = entity.Capacity;
                result.Number = entity.Number;
                result.State = (State)entity.State;
                result.Type = (RoomType)entity.Type;

                foreach (var card in entity.Cards)
                {
                    result.ListOfCards.Add(Card.FromEnityModel(card));
                }
                foreach (var period in entity.Periods)
                {
                    result.Periods.Add(Period.FromEnityModel(period));
                }
            }
            return result;
        }
        /// <summary>
        /// Default constructor
        /// </summary>
        public Room()
        {
            m_ListOfCards = new Collection<Card>();
            m_Periods = new Collection<Period>();
        }

        /// <summary>
        /// Room number
        /// </summary>
        public int Number { get; set; }

        /// <summary>
        /// The current state of the room
        /// </summary>
        public State State { get; set; }

        /// <summary>
        /// Room type
        /// </summary>
        public RoomType Type { get; set; }
        
        /// <summary>
        /// Shows the list of cards that have acces to the room
        /// </summary>
        public Collection<Card> ListOfCards { get { return m_ListOfCards; } set { m_ListOfCards = value; } } 
        
        /// <summary>
        /// List of periods when room is busy
        /// </summary>
        public Collection<Period> Periods { get { return m_Periods; } set { m_Periods = value; } }
      

        /// <summary>
        /// The number of people that can live in room
        /// </summary>
        public int Capacity { get; set; }
        
        public string PartitionKey{get;set;}

        public string RowKey { get; set; }

        public DateTime Timestamp { get; set; }

        /// <summary>
        /// Assignes to recieved object data from current instnce
        /// </summary>
        /// <param name="obj">Object to which the data of current insctnce will be copied</param>
        public void AssignTo(object obj)
        {
            if (obj is Entities.Room)
            {
                Entities.Room result = obj as Entities.Room;

                result.Capacity = Capacity;
                result.Number = Number;
                result.Type = (int)Type;
                result.State = (int)State;

                List<Entities.Period> EntityPeriods = new List<Entities.Period>();
                List<Entities.Period> EntityPeriodsToDelete = new List<Entities.Period>();
                List<Period> PeriodsToUpdate = new List<Period>(Periods);                
                foreach (var entityItem in result.Periods)
                {
                    EntityPeriods.Add(entityItem);
                    if (!PeriodsToUpdate.Exists(p => p.OrderID == entityItem.OrderID))
                    {
                        EntityPeriodsToDelete.Add(entityItem);
                    }
                }

                foreach (var item in EntityPeriodsToDelete)
                {
                    result.Periods.Remove(item);
                }

                foreach (var item in Periods)
                {
                    if (!EntityPeriods.Exists(p => p.OrderID == item.OrderID))
                    {
                        Entities.Period EntityItem = new Entities.Period();
                        item.AssignTo(EntityItem);
                        result.Periods.Add(EntityItem);
                    }
                }

                List<Entities.Card> EntityCards = new List<Entities.Card>();
                foreach (var entityItem in result.Cards)
                {
                    EntityCards.Add(entityItem);
                }

                foreach (var item in ListOfCards)
                {
                    if (!EntityCards.Exists(p => p.OrderID == item.OrderID))
                    {
                        Entities.Card EntityItem = new Entities.Card();
                        item.AssignTo(EntityItem);
                        result.Cards.Add(EntityItem);
                    }
                }
                return;
            }

            throw new NotSupportedException();
        }

        /// <summary>
        /// all card wich grants the access to the current room
        /// </summary>
        private Collection<Card> m_ListOfCards;
        /// <summary>
        /// all periods to wich current room is bond to
        /// </summary>
        private Collection<Period> m_Periods;
    }
}
